<?php
/**
 * Contract class definition
 *  
 * @author Sean Crystal <seancrystal@gmail.com>
 * @package MutantVole
 */   
require_once 'interfaces/iDesignByContract.php';
require_once 'components/exceptions/Exceptions.php';

/**
 * Basic attempt to implement something like Eiffel's design by contract facility.
 * @package MutantVole
 * @subpackage Base
 */   
class Contract implements iDesignByContract {
	/**
     * Check a precondition. Should be used at the top of a method, before any other code is executed.
     * This ensures the calling method has abided by the "contract" defined by the method arguments. 
	 * @param bool $assertion
	 * @param string $error_msg
	 */   	
    public function Precondition($assertion, $error_msg) {
        if (!$assertion) {
            throw new PreconditionFailedException($error_msg);
        }
    }

	/**
     * Check a postcondition. Should be used at the end of a method, before returning. This ensures the
	 * method has kept up its end of the contract in the value returned to the caller.
	 * @param bool $assertion
	 * @param string $error_msg
	 */    	
    public function Postcondition($assertion, $error_msg) {
        if (!$assertion) {
            throw new PostconditionFailedException($error_msg);
        }
    }

	/**
 	 * Check an assertion. Can be used anywhere in a method to verify a condition holds true.
	 * @param bool $assertion
	 * @param string $error_msg   	
     */	
    public function Assertion($assertion, $error_msg) {
        if (!$assertion) {
            throw new AssertionFailedException($error_msg);
        }
    }

	/**
     * Part of eiffel's design by contract facility is an invariant, which is a property that does not change
	 * throughout the lifecycle of an object. PHP provides no easy way to replicate this idea, but it is included
	 * here for the future.
	 * @param bool $assertion
	 * @param string $error_msg    	
     */	
    public function Invariant($assertion, $error_msg) {
        if (!$assertion) {
            throw new InvariantFailedException($error_msg);
        }
    }
}
?>
